<template>
  <drag-dialog :title="title" v-model="visible" width="500px">
    <el-upload
      ref="upload"
      :multiple="multiple"
      :show-file-list="showFileList"
      :limit="limit"
      :accept="accept"
      :action="action"
      :headers="headers"
      :method="method"
      :data="data"
      :before-upload="handleBeforeUpload"
      :on-success="handleFileSuccess"
      :on-error="handleFileError"
      :auto-upload="false"
      :http-request="httpRequest"
      drag
    >
      <el-icon class="el-icon--upload"><upload-filled /></el-icon>
      <div class="el-upload__text">
        将文件拖到此处，或
        <em>点击上传</em>
      </div>
      <template #tip>
        <div class="el-upload__tip">
          <el-link v-if="templateText" type="primary" style="font-size: 12px" @click="handleImportTemplate">{{ templateText }}</el-link>
          <div v-if="tipText" class="el-upload__tip" style="color: red"> {{ tips }} </div>
        </div>
      </template>
    </el-upload>
    <template #footer>
      <el-button type="default" @click="visible = false">{{ cancelText || '取消' }}</el-button>
      <custom-button ref="customButton" :click-banned="true" v-bind="submitBtnVbind" @custom-click="handleSubmit" />
    </template>
  </drag-dialog>
</template>

<script>
import { getParamsWithMerge, executeFunctionsInOrder } from '../../utils/common-methods';
import { uploadApi } from '@code/components/anvil-code-low-common/api/conn';
import { Base64 } from 'js-base64';

export default {
  name: 'UploadDialog',
  props: {
    // 必须的参数默认为false
    modelValue: {
      type: Boolean,
      default: false
    },
    title: {
      type: String,
      default: '文件上传'
    },
    accept: {
      type: String,
      default: ''
    },
    multiple: {
      type: Boolean,
      default: false
    },
    showFileList: {
      type: Boolean,
      default: true
    },
    ajaxSetting: {
      type: Object,
      default: () => {}
    },
    downloadSetting: {
      type: Object,
      default: () => {}
    },
    cancelText: {
      type: String,
      default: '取消'
    },
    templateText: {
      type: String,
      default: ''
    },
    tipText: {
      type: String,
      default: ''
    },
    submitBtn: {
      type: Object,
      default: () => {}
    },
    onSuccess: {
      type: Function,
      default: () => {}
    },
    onError: {
      type: Function,
      default: () => {}
    }
  },
  data() {
    return {
      visible: false
    };
  },
  computed: {
    // 提交按钮的绑定属性
    submitBtnVbind() {
      return {
        ...(this.submitBtn || {}),
        pageId: this.$attrs.pageId
      };
    },
    action() {
      let url = this.ajaxSetting.url || '';
      if (!url.includes(import.meta.env.VITE_APP_BASE_API)) {
        url = import.meta.env.VITE_APP_BASE_API + url;
      }
      return url;
    },
    headers() {
      let Headers = {};
      if (this.ajaxSetting.headers) {
        this.ajaxSetting.headers.forEach((item) => {
          Headers[item.key] = item.value;
        });
      }
      return Headers;
    },
    method() {
      return this.ajaxSetting.method || 'post';
    },
    tips() {
      return this.tipText.replace('${文件类型}', this.accept);
    },
    data() {
      if (this.ajaxSetting && this.ajaxSetting.params) {
        return getParamsWithMerge(this, this.ajaxSetting.params);
      } else {
        return {};
      }
    },
    // 判断是否启用自定义上传逻辑
    httpRequest() {
      if (this.ajaxSetting.type == 'ajax') {
        return (Data) => {
          this.customUploadByApi(this, Data.file, this.ajaxSetting);
        };
      } else {
        return undefined;
      }
    }
  },
  methods: {
    open() {
      this.visible = true;
    },
    handleImportTemplate() {
      if (this.downloadSetting && this.downloadSetting.url) {
        const { url, params, hookBefore } = this.downloadSetting;
        const anvilCodeStore = this.useAnvilCodeStore();
        // 获取当前表单实例
        const { instance } = anvilCodeStore.getPageForm(this.$attrs.pageId);
        let Param = getParamsWithMerge(this, params);
        if (hookBefore) {
          Param = instance[hookBefore](Param);
        }
        this.downloadUrl(this.downloadSetting.url, Param);
      }
    },
    handleFileSuccess(res) {
      if (res && res.code == '200') {
        if (this.onSuccess && typeof this.onSuccess == 'function') {
          this.onSuccess(res);
        }
        this.msgSuccess('上传成功');
        this.$refs.upload.clearFiles();
        this.$refs.customButton.btnFunc();
        this.cancel();
      } else {
        this.handleFileError(res);
      }
    },
    handleFileError(res) {
      if (this.onError && typeof this.onError == 'function') {
        this.onError(res);
      }
      this.msgError('上传失败');
      this.cancel();
    },
    handleBeforeUpload(file) {
      if (this.ajaxSetting.hookBefore) {
        const anvilCodeStore = this.useAnvilCodeStore();
        // 获取当前表单实例
        const { instance } = anvilCodeStore.getPageForm(this.$attrs.pageId);
        return instance[this.ajaxSetting.hookBefore](file);
      } else {
        return true;
      }
    },
    handleSubmit() {
      this.$refs.upload.submit();
    },
    cancel() {
      this.visible = false;
    },
    // 实现自定义的上传回调功能
    customUploadByApi(that, file, setting) {
      try {
        const { url, hookBefore, hookAfter, headers, params } = setting;
        const anvilCodeStore = this.useAnvilCodeStore();
        // 获取当前表单实例
        const { instance } = anvilCodeStore.getPageForm(that.$attrs.pageId);

        // 回调方法， 执行后置钩子
        const callback = (res) => {
          try {
            if (hookAfter) {
              instance[hookAfter](res);
            }
            this.handleFileSuccess(res);
          } catch (e) {
            console.log('customUploadByApi callback error!', e);
          }
        };

        let Header = headers ? { reqHeaderBase64: Base64.encode(JSON.stringify(headers)) } : {};

        const data = getParamsWithMerge(that, params);

        let Param = {
          apiId: url,
          file,
          reqBodyBase64: Base64.encode(JSON.stringify(data))
        };

        // 执行前置钩子
        if (hookBefore) {
          Param = instance[hookBefore](Param);
        }

        return uploadApi(Header, Param)
          .then((res) => {
            callback(res);
          })
          .catch((e) => {
            this.handleFileError(e);
          });
      } catch (e) {
        console.log('customUploadByApi error!', e);
      }
    }
  }
};
</script>